package offer;

import java.util.PriorityQueue;

/**
 * @Author Elephas
 * @Date 2022/2/7
 **/
@FunctionalInterface
public interface LongestDiverseString {
    String longestDiverseString(int a, int b, int c);
}
class LongestDiverseStringImpl1 implements LongestDiverseString{
    static final int[] TEST_01 = new int[]{1,4,5};

    public static void main(String[] args) {
        new LongestDiverseStringImpl1().longestDiverseString(TEST_01[0],TEST_01[1],TEST_01[2]);
    }
    @Deprecated
    @Override
    public String longestDiverseString(int a, int b, int c) {
        if( a == 0 && b == 0 && c ==0){
            return "";
        }
        int sum = a + b + c;
        int maxOfThree = Math.max(Math.max(a,b),c);
        if (maxOfThree == a) {
            return longestDiverseStringHelper(a, b, c, 'a', 'b', 'c');
        } else if (maxOfThree == b) {
            return longestDiverseStringHelper(b, a, c, 'b', 'a', 'c');
        } else {
            return longestDiverseStringHelper(c, a, b, 'c', 'a', 'b');
        }
    }
    private String longestDiverseStringHelperAverage(int f1,int f2,int f3,char c1,char c2,char c3){
        StringBuilder ans = new StringBuilder();
        while(f2 > 0 || f3 > 0){
            if(f1 > 0){
                ans.append(c1);
                f1--;
            }
            if(f2 > 0){
                ans.append(c2);
                f2--;
            }
            if(f3 > 0){
                ans.append(c3);
                f3--;
            }
        }
        if(f1 > 0){
            ans.append(c1);
            f1--;
        }
        if(f1 > 0){
            ans.append(c1);
            f1--;
        }
        return ans.toString();
    }
    private String longestDiverseStringHelper(int f1,int f2,int f3,char c1,char c2,char c3){
        StringBuilder ans = new StringBuilder();
        while(f1 > 0 && (f2 > 0 || f3 > 0)){
            if(f1 > 0){
                ans.append(c1);
                f1--;
            }
            if(f1 > 0){
                ans.append(c1);
                f1--;
            }
            if(f2 > 0 && f3 > 0){
                ans.append(c2);
                f2--;
                if(f1 > 0){
                    ans.append(c1);
                    f1--;
                }
                if(f1 > 0){
                    ans.append(c1);
                    f1--;
                }
                ans.append(c3);
                f3--;
            }else if(f2 > 0){
                ans.append(c2);
                f2--;
            }else{
                ans.append(c3);
                f3--;
            }
        }
        if(f1 > 0){
            ans.append(c1);
            f1--;
        }
        if(f1 > 0){
            ans.append(c1);
            f1--;
        }
        return ans.toString();
    }
}
class LongestDiverseStringImpl2 implements LongestDiverseString{
    @Deprecated
    @Override
    public String longestDiverseString(int a, int b, int c) {
        if( a == 0 && b == 0 && c ==0){
            return "";
        }
        int sum = a + b + c;
        int maxOfThree = Math.max(Math.max(a,b),c);
        if (maxOfThree == a) {
            return longestDiverseStringHelper(a, b, c, 'a', 'b', 'c');
        } else if (maxOfThree == b) {
            return longestDiverseStringHelper(b, a, c, 'b', 'a', 'c');
        } else {
            return longestDiverseStringHelper(c, a, b, 'c', 'a', 'b');
        }
    }
    private String longestDiverseStringHelper(int f1,int f2,int f3,char c1,char c2,char c3){
        StringBuilder ans = new StringBuilder();
        while(f1 > 0 && (f2 > 0 || f3 > 0)){
            if(f1 > 0){
                ans.append(c1);
                f1--;
            }
            if(f1 > 0){
                ans.append(c1);
                f1--;
            }
            if(f2 > f3){
                ans.append(c2);
                f2--;
            }else{
                ans.append(c3);
                f3--;
            }
            if(f1 <= f2 || f1 <= f3){
                int tempF = f1;
                char tempC = c1;
                if(f2 > f3){
                    f1 = f2;
                    f2 = tempF;
                    c1 = c2;
                    c2 = tempC;
                }else{
                    f1 = f3;
                    f3 = tempF;
                    c1 = c3;
                    c3 = tempC;
                }
            }
        }
        if(f1 > 0){
            ans.append(c1);
            f1--;
        }
        if(f1 > 0){
            ans.append(c1);
            f1--;
        }
        return ans.toString();
    }
}

class LongestDiverseStringImpl3 implements LongestDiverseString{

    /**
     * 贪心法做出不出来，抄题解了，思路为构建一个最大堆，每次取堆顶元素
     * @param a
     * @param b
     * @param c
     * @return
     */
    @Override
    public String longestDiverseString(int a, int b, int c) {
        PriorityQueue<int[]> queue = new PriorityQueue<>((x,y)->y[1]-x[1]);
        if(a > 0){
            queue.add(new int[]{0,a});
        }
        if(b > 0){
            queue.add(new int[]{1,b});
        }
        if(c > 0){
            queue.add(new int[]{2,c});
        }
        StringBuilder ans = new StringBuilder();
        while(!queue.isEmpty()){
            int[] cur = queue.poll();
            int n = ans.length();
            if(n >= 2 && ans.charAt(n - 1) - 'a' == cur[0] && ans.charAt(n - 2) - 'a' == cur[0]){
                if(queue.isEmpty()){
                    break;
                }
                int[] next = queue.poll();
                ans.append((char)(next[0] + 'a'));
                if(--next[1] != 0){
                    queue.add(next);
                }
                queue.add(cur);
            }else{
                ans.append((char)(cur[0] + 'a'));
                if(--cur[1] != 0){
                    queue.add(cur);
                }
            }
        }
        return ans.toString();
    }
}